# -*- coding: utf-8 -*-
"""
Created on Wed Nov 18 16:18:08 2020

@author: weifeng.zhang
"""

import os
from typing import Optional
import json

from fastapi import FastAPI, File, Form, UploadFile

from starlette.responses import FileResponse
from starlette.requests import Request
from starlette.templating import Jinja2Templates
from starlette.staticfiles import StaticFiles

from algorithm import BaseAlgorithm
from algorithm import ModelBean
from algorithm import AlgorithmBean

app = FastAPI()

# 创建一个templates（模板）对象，以后可以重用。
templates = Jinja2Templates(directory="templates")
app.mount('/templates',StaticFiles(directory='templates'),name='templates')

'''
获取算法列表
包括算法名称、算法编码、算法描述、算法文档、算法训练模型模板文件
'''
@app.get("/AIUama")
def get_algorithm_lt(request: Request):
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    print(algorithmLt)
    return algorithmLt


'''
获取算法定义及模型列表
'''
@app.get("/AIUama/view/{algorithm_code}")
def get_algorithm(algorithm_code: str):
    #算法列表
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    #算法明细
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    models = baseal.getModelltByAlgorithmCode(algorithm_code)
    return {"algorithm":algorithm,"models":models}




'''
获取模型明细
'''
@app.get("/AIUama/view/{algorithm_code}/{model_code}")
def get_algorithm(algorithm_code: str,model_code: str):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
        return {"msg":"算法不存在！"}
    
    model = baseal.getModelByCode(algorithm_code,model_code)
    if model is None:
        return  {"msg":"模型不存在！"}
      
    return model

'''
添加算法对应的模型 
'''
@app.post("/AIUama/model/add/{algorithm_code}")  
async def addModel(algorithm_code: str , model_name: str = Form(...), model_code: str = Form(...),model_desc: str = Form(...),training_file: UploadFile = File(...)):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
          return {"msg":"算法不存在！"}  
    
    #存储到算法目录下面
    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "models" + os.sep + algorithm_code
    modelPath = basedir + os.sep + model_code
    isExists = os.path.exists(modelPath)
    #判断文件夹是否存在
    if isExists:
        return {"msg":"模型对应code已经存在，请修改后再创建！"}
    #创建文件夹
    os.makedirs(modelPath) 
    #上传训练模型文件
    contents = await training_file.read()
    training_file_path = modelPath + os.sep + training_file.filename
    with open(f"{training_file_path}",'wb') as f:
        #for i in iter(lambda : training_file.file.read(1024*1024*10),b""):
        #    f.write(i)
        f.write(contents)
    f.close()
    
    #存储模型信息
    model = ModelBean(algorithm_code,model_name,model_code,model_desc,training_file.filename,"")
    baseal.addModel(model)
    return model



'''
暂时不开放
@app.post("/AIUama/model/uploadtrain/{algorithm_code}/{model_code}") 
async def  uploadTrainFile(algorithm_code: str,model_code: str,training_file: UploadFile = File(...)):
    contents = await training_file.read()
    
    basedir = os.path.abspath(os.path.dirname(__file__))
    # 默认下载训练模型文件Z
    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "models"
    algorithmdir = basedir + os.sep + algorithm_code
    modelmdir = algorithmdir + os.sep + model_code
    file_path = modelmdir + os.sep + training_file.filename
    with open(f"{file_path}",'wb') as f:
        #for i in iter(lambda : training_file.file.read(1024*1024*10),b""):
        #    f.write(i)
        f.write(contents)
    f.close()

    return {"msg":"上传成功！"}
'''


'''
训练模型
'''
@app.get("/AIUama/model/training/{algorithm_code}/{model_code}")
async def trainningModel(algorithm_code: str,model_code: str):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
        return {"msg":"算法不存在！"}
    
    model = baseal.getModelByCode(algorithm_code,model_code)
    if model is None:
        return  {"msg":"模型不存在！"}
    
    result = baseal.trainingModel(algorithm,model)
    return {"msg":result}


'''
调用模型
'''
@app.post("/AIUama/model/call/{algorithm_code}/{model_code}")
def callModel(algorithm_code: str,model_code: str,params: str = Form(...)):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
        return {"msg":"算法不存在！"}
    
    model = baseal.getModelByCode(algorithm_code,model_code)
    if model is None:
        return  {"msg":"模型不存在！"}
    
    result = baseal.callModel(algorithm,model,params)
    return {"msg":result}

'''
下载文件Z
包括算法文档、算法训练模型模板文件的下载
'''
@app.get("/AIUama/download/{algorithm_code}/{file_name}")
def download(request: Request,algorithm_code: str, file_name: str):
    print(file_name)
    #算法列表
    #algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    #baseal = BaseAlgorithm()
    #algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    
    #获取工程目录
    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "models"
    algorithmdir = basedir + os.sep + algorithm_code
    file_path = algorithmdir + os.sep + file_name
    print(file_path)
    return FileResponse(file_path)


'''
下载文件Z
包括算法文档、算法训练模型模板文件的下载
'''
@app.get("/AIUama/download/{algorithm_code}/{model_code}/{file_name}")
def download(request: Request,algorithm_code: str,model_code: str ,file_name: str):
    print(file_name)
    #算法列表
    #algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    #baseal = BaseAlgorithm()
    #algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    
    #获取工程目录
    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "models"
    algorithmdir = basedir + os.sep + algorithm_code
    modelmdir = algorithmdir + os.sep + model_code
    file_path = modelmdir + os.sep + file_name
    print(file_path)
    return FileResponse(file_path)


'''
获取算法列表
包括算法名称、算法编码、算法描述、算法文档、算法训练模型模板文件
'''
@app.get("/page/AIUama")
def get_algorithm_lt(request: Request):
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    print(algorithmLt)
    return templates.TemplateResponse("index.html", {"request": request, "algorithmLt": algorithmLt})

'''
获取算法定义及模型列表
'''
@app.get("/page/AIUama/view/{algorithm_code}")
def get_algorithm(request: Request,algorithm_code: str):
    #算法列表
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    #算法明细
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    models = baseal.getModelltByAlgorithmCode(algorithm_code)
    return templates.TemplateResponse("algorithm.html", {"request": request, "algorithm": algorithm,"models":models})

'''
添加算法对应的模型 
'''
@app.get("/page/AIUama/model/add/{algorithm_code}")  
def addModel(request: Request,algorithm_code: str ):
    return templates.TemplateResponse("addmodel.html", {"request": request, "algorithm_code": algorithm_code})


'''
添加算法对应的模型 
'''
@app.post("/page/AIUama/model/add/{algorithm_code}")  
async def addModel(request: Request,algorithm_code: str , model_name: str = Form(...), model_code: str = Form(...),model_desc: str = Form(...),training_file: UploadFile = File(...)):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
          return {"msg":"算法不存在！"}  
    
    #存储到算法目录下面
    basedir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "models" + os.sep + algorithm_code
    modelPath = basedir + os.sep + model_code
    isExists = os.path.exists(modelPath)
    #判断文件夹是否存在
    if isExists:
        return {"msg":"模型对应code已经存在，请修改后再创建！"}
    #创建文件夹
    os.makedirs(modelPath) 
    #上传训练模型文件
    contents = await training_file.read()
    training_file_path = modelPath + os.sep + training_file.filename
    with open(f"{training_file_path}",'wb') as f:
        #for i in iter(lambda : training_file.file.read(1024*1024*10),b""):
        #    f.write(i)
        f.write(contents)
    f.close()
    
    #存储模型信息
    model = ModelBean(algorithm_code,model_name,model_code,model_desc,training_file.filename,"")
    baseal.addModel(model)
    
    models = baseal.getModelltByAlgorithmCode(algorithm_code)
    return templates.TemplateResponse("algorithm.html", {"request": request, "algorithm": algorithm,"models":models})


'''
调用模型
'''
@app.get("/page/AIUama/model/call/{algorithm_code}/{model_code}")
def callModel(request: Request,algorithm_code: str,model_code: str):
    #得到算法
    algorithmLt = BaseAlgorithm.getAlgorithmlt(BaseAlgorithm)
    baseal = BaseAlgorithm()
    algorithm = baseal.getAlgorithmByCode(algorithm_code,algorithmLt)
    if algorithm is None:
        return {"msg":"算法不存在！"}
    
    model = baseal.getModelByCode(algorithm_code,model_code)
    if model is None:
        return  {"msg":"模型不存在！"}
    
    return templates.TemplateResponse("callmodel.html", {"request": request, "algorithm": algorithm,"model":model})

    